<template>
    <div class="KnowledgeBase">
        <div style="display: flex; margin-bottom: 20px">
            <div
                class="el-input el-input-group el-input-group--prepend"
                style="margin-right: 10px"
            >
                <div class="el-input-group__prepend">故障类型</div>
                <el-select
                    v-model="queryCondition.faultType"
                    style="width: calc(100%)"
                    clearable
                    placeholder="查找故障类型"
                >
                    <el-option
                        v-for="item in faults"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value"
                    >
                    </el-option>
                </el-select>
            </div>
            <div
                class="el-input el-input-group el-input-group--prepend"
                style="margin-right: 10px"
            >
                <div class="el-input-group__prepend">故障设备</div>
                <el-select
                    v-model="queryCondition.faultDevice"
                    style="width: calc(100%)"
                    clearable
                    placeholder="查找故障设备"
                >
                    <el-option
                        v-for="item in queryCondition.faultType
                            ? faults.find(
                                  (f) => f.value === queryCondition.faultType
                              ).children
                            : faultList"
                        :key="item.value"
                        :label="item.label"
                        :value="item.label"
                    >
                    </el-option>
                </el-select>
            </div>
            <el-input
                placeholder="查找专家"
                v-model="queryCondition.expertName"
                style="margin-right: 20px"
            >
                <template slot="prepend">专家名称</template>
            </el-input>
            <el-button class="el-icon-search" @click="list" type="primary" />
            <el-button
                class="el-icon-plus"
                type="success"
                @click="openDialog(null, true)"
                v-show="userType !== 0"
            />
        </div>

        <el-table :data="diagnosis.list" border style="margin-bottom: 20px">
            <el-table-column type="index" width="50"> </el-table-column>
            <el-table-column prop="faultType" label="故障类型" />
            <el-table-column prop="faultDevice" label="故障设备" width="200" />
            <el-table-column prop="desc" label="故障描述" width="300" />
            <el-table-column label="故障图片" width="300">
                <template slot-scope="scope">
                    <div style="display: flex; justify-content: center">
                        <img
                            :src="getFaultImage(scope.row.id)"
                            alt=""
                            style="width: 80%"
                        />
                    </div>
                </template>
            </el-table-column>
            <el-table-column prop="reason" label="故障原因" width="300" />
            <el-table-column prop="solution" label="诊断方案" width="500" />
            <el-table-column prop="expertName" label="专家名称" />
            <el-table-column
                label="操作"
                width="70"
                fixed="right"
                v-show="userType !== 0"
            >
                <template slot-scope="scope">
                    <div
                        style="
                            display: flex;
                            flex-direction: column;
                            align-items: center;
                            justify-content: center;
                        "
                    >
                        <el-button
                            @click="openDialog(scope.row, false)"
                            size="mini"
                            style="margin-bottom: 10px"
                            >编辑</el-button
                        >
                        <el-button
                            type="danger"
                            size="mini"
                            style="margin-left: 0"
                            @click="removeDiagnosis(scope.row.id)"
                            >删除</el-button
                        >
                    </div>
                </template>
            </el-table-column>
        </el-table>
        <div style="width: 100%; display: flex; justify-content: flex-end">
            <el-pagination
                background
                @size-change="handlePageSizeChange"
                @current-change="handlePageNoChange"
                :current-page="queryCondition.pageNo"
                :page-sizes="[5, 10, 20, 50]"
                :page-size="queryCondition.pageSize"
                layout="total, sizes, prev, pager, next"
                :total="diagnosis.total"
            >
            </el-pagination>
        </div>

        <el-dialog
            :title="
                isCreate ? '知识文档新建' : modifyDocInfo.id + ' 知识文档修改'
            "
            :visible.sync="modifyVisible"
            @close="closeDialog"
            :append-to-body="true"
            width="60%"
        >
            <div
                style="display: flex; align-items: center; margin-bottom: 20px"
            >
                <div style="font-weight: 500; margin-right: 20px; width: 70px">
                    故障
                </div>
                <el-cascader
                    v-model="modifyDocInfo.faultValue"
                    :options="faults"
                    @change="handleDocInfoFaultChange"
                />
            </div>
            <div
                style="display: flex; align-items: center; margin-bottom: 20px"
            >
                <div style="font-weight: 500; margin-right: 20px; width: 80px">
                    故障描述
                </div>
                <el-input type="text" v-model="modifyDocInfo.desc" />
            </div>
            <div style="display: flex; margin-bottom: 20px">
                <div style="font-weight: 500; margin-right: 10px; width: 80px">
                    故障图片
                </div>
                <el-upload
                    class="fault-png-uploader"
                    :show-file-list="false"
                    :on-change="uploadFaultChange"
                    :auto-upload="false"
                    action="这是一个无效的地址"
                >
                    <img
                        v-if="modifyDocInfo.faultForBase64 !== ''"
                        :src="modifyDocInfo.faultForBase64"
                        alt=""
                        class="fault-png"
                    />
                    <i
                        v-else
                        class="el-icon-picture-outline-round fault-png-uploader-icon"
                    ></i>
                </el-upload>
            </div>
            <div
                style="display: flex; align-items: center; margin-bottom: 20px"
            >
                <div style="font-weight: 500; margin-right: 20px; width: 80px">
                    故障原因
                </div>
                <el-input type="text" v-model="modifyDocInfo.reason" />
            </div>
            <div style="display: flex; margin-bottom: 20px">
                <div style="font-weight: 500; margin-right: 20px; width: 80px">
                    诊断方案
                </div>
                <el-input
                    type="textarea"
                    :autosize="{ minRows: 10, maxRows: 10 }"
                    resize="none"
                    v-model="modifyDocInfo.solution"
                />
            </div>
            <div style="display: flex; align-items: center">
                <div style="font-weight: 500; margin-right: 20px; width: 80px">
                    专家名称
                </div>
                <div>{{ isCreate ? username : modifyDocInfo.expertName }}</div>
            </div>
            <div
                style="
                    display: flex;
                    align-items: center;
                    justify-content: center;
                "
            >
                <el-button size="small" @click="closeDialog">取消</el-button>
                <el-button type="primary" size="small" @click="submitDiagnosis"
                    >提交</el-button
                >
            </div>
        </el-dialog>
    </div>
</template>

<script>
import * as diagApi from "@/api/diagnosis";
import { fileToBase64, getFault } from "@/utils";
import { nonEmptyValidator, regularPassword } from "@/rules";

export default {
    name: "KnowledgeBase",
    data() {
        return {
            username: "",
            userType: 0,
            faults: {},
            diagnosis: {},
            queryCondition: {
                pageNo: 1,
                pageSize: 10,
                faultType: "",
                faultDevice: "",
                expertName: "",
            },

            modifyDocInfo: {
                id: "",
                faultValue: "",
                faultForBase64: "",
                desc: "",
                reason: "",
                solution: "",
                expertName: "",
            },
            modifyVisible: false,
            isCreate: false,
            faultList: [],
        };
    },
    async mounted() {
        await this.listFaults();
        await this.list();
        this.username = JSON.parse(localStorage.getItem("userinfo")).username;
        this.userType = JSON.parse(localStorage.getItem("userinfo")).type;

        this.faultList = this.faults.reduce((pre, cur) => {
            pre.push(...cur.children);
            return pre;
        }, []);
    },
    methods: {
        async listFaults() {
            const res = await diagApi.listFaults();
            if (res.data.code === 0) {
                this.faults = transformFaults2CascaderData(res.data.data);
            } else {
                this.$message.error(res.data.msg);
            }
        },
        async list() {
            const res = await diagApi.list(this.queryCondition);
            if (res.data.code === 0) {
                this.diagnosis = res.data.data;
            } else {
                this.$message.error(res.data.msg);
            }
        },
        async removeDiagnosis(id) {
            const res = await diagApi.remove(id);
            if (res.data.code === 0) {
                this.$message.success(res.data.msg);
                await this.list();
            } else {
                this.$message.error(res.data.msg);
            }
        },
        async submitDiagnosis() {
            const infoMap = {
                faultId: "故障选择",
                desc: "故障描述",
                faultForBase64: "故障图片",
                reason: "故障原因",
                solution: "诊断方案",
            };
            for (let key in infoMap) {
                if (
                    this.modifyDocInfo[key] == null ||
                    this.modifyDocInfo[key].length < 1
                ) {
                    this.$message.error(`${infoMap[key]}未填写`);
                    return;
                }
            }
            const res = await diagApi.save(this.modifyDocInfo);
            if (res.data.code === 0) {
                this.$message.success(res.data.msg);
                await this.list();
                this.closeDialog();
            } else {
                this.$message.error(res.data.msg);
            }
        },

        openDialog(data, isCreate) {
            this.modifyVisible = true;
            this.isCreate = isCreate;

            if (isCreate === false) {
                this.modifyDocInfo.id = data.id;
                this.modifyDocInfo.desc = data.desc;
                this.modifyDocInfo.reason = data.reason;
                this.modifyDocInfo.solution = data.solution;
                this.modifyDocInfo.expertName = data.expertName;
                this.modifyDocInfo.faultType = data.faultType;
                this.modifyDocInfo.faultDevice = data.faultDevice;
                getImageFile(
                    "proxy/img_of_fault/" +
                        data.id +
                        ".png?timestamp=" +
                        Date.now()
                )
                    .then((file) => {
                        return fileToBase64(file);
                    })
                    .then((base64) => {
                        this.modifyDocInfo.faultForBase64 = base64;
                    });
                this.modifyDocInfo.faultValue = [];
                this.modifyDocInfo.faultValue.push(
                    this.modifyDocInfo.faultType
                );
                for (let i = 0; i < this.faults.length; i++) {
                    for (let j = 0; j < this.faults[i].children.length; j++) {
                        if (
                            this.faults[i].children[j].label ===
                            this.modifyDocInfo.faultDevice
                        ) {
                            this.modifyDocInfo.faultValue.push(
                                this.faults[i].children[j].value
                            );
                            this.modifyDocInfo.faultId =
                                this.faults[i].children[j].value;
                        }
                    }
                }
            }
        },
        closeDialog() {
            this.modifyVisible = false;
            this.modifyDocInfo.desc = "";
            this.modifyDocInfo.reason = "";
            this.modifyDocInfo.solution = "";
            this.modifyDocInfo.expertName = "";
            this.modifyDocInfo.faultType = "";
            this.modifyDocInfo.faultDevice = "";
            this.modifyDocInfo.faultValue = [];
            this.modifyDocInfo.faultForBase64 = "";
            this.modifyDocInfo.id = null;
        },
        uploadFaultChange(file) {
            if (file.raw.type !== "image/png") {
                this.$message.error("图片仅能为 png 格式");
                return;
            }
            toBase64(file).then((res) => {
                this.modifyDocInfo.faultForBase64 = res;
            });
        },

        handlePageNoChange(pageNo) {
            this.queryCondition.pageNo = pageNo;
            this.list();
        },
        handlePageSizeChange(pageSize) {
            this.queryCondition.pageSize = pageSize;
            this.list();
        },
        handleDocInfoFaultChange(e) {
            this.modifyDocInfo.faultId = e[1];
        },
        getFaultImage(id) {
            return getFault(id);
        },
    },
};

function transformFaults2CascaderData(data) {
    const result = [];
    for (const key in data) {
        const item = data[key];
        const children = [];
        for (const subItem of item.subItems) {
            children.push({
                value: subItem.id,
                label: subItem.device,
            });
        }
        result.push({
            value: item.type,
            label: item.type,
            children: children,
        });
    }
    return result;
}
function toBase64(file) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        let fileResult = "";
        reader.readAsDataURL(file.raw);
        reader.onload = () => (fileResult = reader.result);
        reader.onerror = (error) => reject(error);
        reader.onloadend = () => resolve(fileResult);
    });
}
function getImageFile(url) {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.open("GET", url, true);
        xhr.responseType = "blob";
        xhr.onload = () => {
            if (xhr.status === 200) {
                resolve(xhr.response);
            } else {
                reject(new Error(xhr.statusText));
            }
        };
        xhr.onerror = () => {
            reject(new Error("Network error"));
        };
        xhr.send();
    });
}
</script>

<style lang='less'>
.KnowledgeBase {
    width: 100%;
    overflow-y: auto;

    .dialog-item {
        width: 100%;
        display: flex;
        flex-direction: row;
        align-items: center;
    }

    .el-input-group--append .el-select .el-input.is-focus .el-input__inner,
    .el-input-group--prepend .el-select .el-input.is-focus .el-input__inner {
        border-color: #409eff;
    }
}
.fault-png-uploader {
    display: flex;
    justify-content: center;
}

.fault-png-uploader .el-upload {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
}

.fault-png-uploader .el-upload:hover {
    border-color: #409eff;
}

.fault-png-uploader-icon {
    font-size: 40px;
    color: #8c939d;
    width: 200px;
    height: 100px;
    line-height: 100px;
    text-align: center;
}

.fault-png {
    width: 200px;
    height: 100px;
    display: block;
}
</style>